package de.cube3d.blitwit.space 
{
	import flash.geom.Rectangle;
	import de.cube3d.blitwit.render.BlitSpriteScene;
	
	/**
	 * A space can be understood like a layer that can be filled with sprites. 
	 * This is a baseclass that is without meaningful functionality and must be overloaded
	 * like the BTSpace class is doing.
	 * 
	 * The base class is 
	 */
	public class Space 
	{
		protected var area:Rectangle = new Rectangle();
		protected var _totalContentCount:int = 0;
		protected var _owner:BlitSpriteScene;
		public var isAnimated:Boolean = true;
		
		
		public function Space(x:Number, y:Number, width:Number, height:Number) 
		{
			area.width = width;
			area.height = height;
			area.x = x;
			area.y = y;
			
		}
		
		public function get x ():Number {
			return area.x;
		}
		public function get y():Number { 
			return area.y;
		}
		public function get width():Number {
			return area.width;
		}
		public function get height():Number {
			return area.height;
		}
		
		/**
		 * Enables or disables the animation flag of this space (you can also access
		 * the public variable "isAnimated", it's just a flag). 
		 * Disabling animations will prevent the scene from requesting elements from
		 * this space in order to call their animation functions. That may help to
		 * improve the performance in case of static background spaces. The default 
		 * value is on.
		 * 
		 * @param	on
		 * @return self
		 */
		public function setAnimated (on:Boolean):Space {
			isAnimated = on;
			return this;
		}
		
		public function get totalContentCount():int {
			return _totalContentCount;
		}
		
		public function get owner ():BlitSpriteScene {
			return _owner;
		}
		
		public function set owner (owner:BlitSpriteScene):void{
			_owner = owner;
		}
		
		public function setOwner (owner:BlitSpriteScene):Space {
			this.owner = owner;
			return this;
		}
		
		public function get isEmpty ():Boolean {
			return true;
		}
		
		public function add (bs:SpaceObject):Boolean {
			if (!bs.intersects(area)) return false; // don't insert stuff that's not at least a bit inside
			if (bs.owner == this || !_internalAdd(bs)) return false;
			bs.owner = this;
			_totalContentCount += 1;
			return true;
		}
		
		protected function _internalAdd (bs:SpaceObject):Boolean {
			return false;
		}
		
		public function remove (bs:SpaceObject):Boolean {
			if (bs.owner != this || _internalRemove(bs)) return false;
			_totalContentCount -= 1;
			return true;
		}
		
		protected function _internalRemove (bs:SpaceObject):Boolean {
			return false;
		}
		
		public function enlistContent (area:Rectangle, appendTo:Vector.<SpaceObject>)
			:Vector.<SpaceObject> {
			return appendTo;
		}
		
		public function getObjectsAt (x:Number, y:Number, appendTo:Vector.<SpaceObject>)
			:Vector.<SpaceObject> {
			return appendTo;
		}
		
		public function sortIndexChanged(obj:SpaceObject, oldidx:Number, newidx:Number):Space {
			owner.markArea(obj.x, obj.y, obj.width, obj.height);
			return this;
		}
		
		public function objectMoved(obj:SpaceObject, oldx:Number, oldy:Number, newx:Number, newy:Number): Space {
			// must be overriden
			throw new Error("This space doesn't support moving objects");
		}
	}

}